package cn.exrick.xboot.modules.your;

import cn.exrick.xboot.common.annotation.RateLimiter;
import cn.exrick.xboot.common.jiuqiCommon.callAPIUtil.CallApiUtil;
import cn.exrick.xboot.common.lock.Callback;
import cn.exrick.xboot.common.lock.RedisDistributedLockTemplate;
import cn.exrick.xboot.common.utils.IpInfoUtil;
import cn.exrick.xboot.common.utils.PageUtil;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.modules.AccessControl.AccessControlUserDto.AcForm;
import cn.exrick.xboot.modules.AccessControl.entity.AccessControlUser;
import cn.exrick.xboot.modules.AccessControl.serviceimpl.IAccessControlUserServiceImpl;
import cn.exrick.xboot.modules.backlogOrFullList.service.IbacklogOrFullListService;
import cn.exrick.xboot.modules.backlogOrFullList.utils.BacklogUtile;
import cn.exrick.xboot.modules.base.dao.mapper.UserMapper;
import cn.exrick.xboot.modules.base.entity.Role;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.RoleService;
import cn.exrick.xboot.modules.base.service.mybatis.IUserService;
import cn.exrick.xboot.modules.subsystemNews.entity.SubsystemNews;
import cn.exrick.xboot.modules.subsystemNews.service.ISubsystemNewsService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author Exrickx
 */
@Slf4j
@Controller
@Api(description = "测试接口 无需登录验证")
@Transactional
@RequestMapping("/xboot/test")
public class TestController {
    @Autowired
    private RedisDistributedLockTemplate lockTemplate;
    @Autowired
    private RoleService roleService;
    @Autowired
    private IbacklogOrFullListService ibacklogOrFullListService;
    @Autowired
    ISubsystemNewsService iSubsystemNewsService;

    @Autowired
    private IpInfoUtil ipInfoUtil;
    @Autowired
    private SpringbootTimeTest springbootTimeTest;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private IAccessControlUserServiceImpl iAccessControlUserService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IUserService iUserService;

    @RequestMapping(value = "/lockAndLimit",method = RequestMethod.GET)
    @RateLimiter(limit = 1, timeout = 5000)
    @ApiOperation(value = "同步锁限流测试")
    @ResponseBody
    public Result<Object> test(){

        lockTemplate.execute("订单流水号", 5000, new Callback() {
            @Override
            public Object onGetLock() throws InterruptedException {
                //TODO 获得锁后要做的事
                log.info("生成订单流水号");
                return null;
            }

            @Override
            public Object onTimeout() throws InterruptedException {
                //TODO 获得锁超时后要做的事
                return null;
            }
        });
        return new ResultUtil<Object>().setData(null);
    }
    @RequestMapping(value = "/getRole", method = RequestMethod.GET)
    @ApiOperation(value = "通过id获取")
    public String  getRole(){
        List<Role> byName = roleService.findByName("ROLE_USER");
        System.out.println(byName.size());
        return "111";
    }

    /*@RequestMapping(value = "/sendBacklogAngleToAPP", method = RequestMethod.GET)
    @ApiOperation(value = "测试向app推送待办")
    public String  sendBacklogAngleToAPP(){
        System.out.println("测试向app推送待办");
        ibacklogOrFullListService.sendBacklogAngleToAPP("njp");
        return "111";
    }*/

    @RequestMapping(value = "/selectBacklogAngleNum", method = RequestMethod.GET)
    @ApiOperation(value = "查询当前用户的待办数量")
    public String  selectBacklogAngleNum(){
        System.out.println("查询当前用户的待办数量");
        Integer tw = ibacklogOrFullListService.selectBacklogAngleNum("tw");
        System.out.println(tw);
        return ""+tw;
    }

    @RequestMapping(value = "/removeByMap", method = RequestMethod.GET)
    @ApiOperation(value = "/removeByMap")
    public void  removeByMap(){
        Map<String,Object> map=new HashMap<>();
        map.put("info_id","test");
        iSubsystemNewsService.removeByMap(map);
    }
    @RequestMapping(value = "/listByMap", method = RequestMethod.GET)
    @ApiOperation(value = "/listByMap")
    public void  listByMap(){
        Map<String,Object> map=new HashMap<>();
        map.put("info_id","test");
        //Collection<SubsystemNews> subsystemNews = iSubsystemNewsService.listByMap(map);
        List<SubsystemNews> subsystemNews=new ArrayList<>(iSubsystemNewsService.listByMap(map));
        for (SubsystemNews subsystemNew : subsystemNews) {
            System.out.println(subsystemNew.toString());
        }
    }


    @RequestMapping(value = "/iptest", method = RequestMethod.GET)
    @ApiOperation(value = "")
    public void  iptest(HttpServletRequest request){
        String ipAddr = ipInfoUtil.getIpAddr(request);
        log.info("客户端IP地址"+ipAddr);
        //开始判断IP地址
        boolean b = MyTest.internalIp(ipAddr);
        log.info( b ? "内网地址ip": "外网地址ip");
    }

    @RequestMapping(value = "/timetest", method = RequestMethod.GET)
    @ApiOperation(value = "springboot的EnableScheduling 自带定时任务测试")
    public void  EnableScheduling(HttpServletRequest request){
       log.info("开始springboot的EnableScheduling 自带定时任务测试");
        springbootTimeTest.timeOut();

    }

    @RequestMapping(value = "/redisPipeline", method = RequestMethod.POST)
    @ApiOperation(value = "redis的管道 pipeline 添加数据测试")
    public void  redistest(){
        log.info("redistest开始");
        // 开始时间
        long start = System.currentTimeMillis();
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        List<String> result = redisTemplate.executePipelined(new SessionCallback() {
            //执行流水线
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                //批量处理的内容
                for (int i = 0; i < 20000; i++) {
                    operations.opsForValue().set("redistest:" + "k" + i, "v" + i);
                }
                //注意这里一定要返回null，最终pipeline的执行结果，才会返回给最外层
                return null;
            }
        });
        // 结束时间
        long end = System.currentTimeMillis();
        log.info("运行时间："+(end-start));
        }

    @RequestMapping(value = "/redisPipeline", method = RequestMethod.DELETE)
    @ApiOperation(value = "redis的管道 pipeline删除测试")
    public void  redisDeletetest(){
        log.info("redistest开始");
        // 开始时间
        long start = System.currentTimeMillis();
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        redisTemplate.executePipelined(new SessionCallback() {
            //执行流水线
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                //批量处理的内容
                for (int i = 0; i < 20000; i++) {
                    //operations.opsForValue().set("redistest:"+"k"+i,"v"+i);
                    operations.delete("redistest:"+"k"+i);
                    System.out.println(i);
                }
                return null;
            }
        });
        // 结束时间
        long end = System.currentTimeMillis();
        log.info("运行时间："+(end-start));
    }
  /*  @RequestMapping(value = "/redisPipeline", method = RequestMethod.GET)
    @ApiOperation(value = "redis的管道 pipeline GET测试")
    public void  redisGettest(){
        log.info("redistest开始");
        // 开始时间
        long start = System.currentTimeMillis();
         redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations redisOperations) throws DataAccessException {
                redisOperations.opsForValue().set("wanwan", "123456");
                String myValue = String.valueOf(redisOperations.opsForValue().get("wanwan"));
                System.out.println(myValue);
                return myValue;
            }
        });
        // 结束时间
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }*/


    /**
     * redis 批量操作其中一种方式
     * redis pipeline 管道技术
     */
    @RequestMapping(value = "/redisPipeline", method = RequestMethod.GET)
    @ApiOperation(value = "redis的管道 pipeline GET测试")
    public void redisPipeline(){
        RedisSerializer stringSerializer = new StringRedisSerializer();
        stringRedisTemplate.setKeySerializer(stringSerializer);
        stringRedisTemplate.setValueSerializer(stringSerializer);
        List<String>  keys=new ArrayList();
        for (int i = 0; i < 200; i++) {
            keys.add("redistest:"+"k"+i);
        }
        Map<String, Object> stringObjectMap = batchQueryByKeys(keys, true);
        System.out.println(stringObjectMap.size());
    }

    /**
     *
     * @param keys
     * @param useParallel  是否使用并行平行流
     * @return
     */
    public Map<String,Object> batchQueryByKeys(List<String> keys,Boolean useParallel){
        if(null == keys || keys.size() == 0 ){
            return null;
        }
        if(null == useParallel){
            useParallel = true;
        }
        List<Object> results = stringRedisTemplate.executePipelined(
                new RedisCallback<Object>() {
                    @Override
                    public Object doInRedis(RedisConnection connection) throws DataAccessException {
                        StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
                        for(String key:keys) {
                            stringRedisConn.get(key);
                        }
                        return null;
                    }
                });
        if(null == results || results.size() == 0 ){return null;}
        Map<String,Object> resultMap  =  null;
        if(useParallel){
            Map<String,Object> resultMapOne  = Collections.synchronizedMap(new HashMap<String,Object>());
            keys.parallelStream().forEach(t -> {
                resultMapOne.put(t,results.get(keys.indexOf(t)));
            });
            resultMap = resultMapOne;
        }else{
            Map<String,Object> resultMapTwo  = new HashMap<>();
            for(String t:keys){
                resultMapTwo.put(t,results.get(keys.indexOf(t)));
            }
            resultMap = resultMapTwo;
        }
        return  resultMap;
    }

    @RequestMapping(value = "/delAcu", method = RequestMethod.GET)
    @ApiOperation(value = "acu 删除测试")
    public String  delAcu(@ModelAttribute AccessControlUser accessControlUser){
        List<AccessControlUser> accessControlUserList=new ArrayList<>();
        accessControlUserList.add(accessControlUser);
        iAccessControlUserService.delAccessControlBySys(accessControlUserList);
        return "111";
    }

    @RequestMapping(value = "/findAcuBySysAndUser", method = RequestMethod.GET)
    @ApiOperation(value = "findAcuBySysAndUser测试")
    public String  findAcuBySysAndUser(@ModelAttribute AccessControlUser accessControlUser){
        List<AccessControlUser> acuBySysAndUser = iAccessControlUserService.findAcuBySysAndUser(accessControlUser);
       log.info( acuBySysAndUser.toString());
        return "111";
    }

    @RequestMapping(value = "/callFD", method = RequestMethod.GET)
    @ApiOperation(value = "测试获取待办信息")
    public void  callFD(){
        RestTemplate restTemplate=new RestTemplate();
        JSONObject jsonObject = new CallApiUtil().javaToJSON();

        JSONObject json = restTemplate.postForEntity("http://10.1.13.14:8030/getBacklogByCondition", jsonObject, JSONObject.class).getBody();
        System.out.println(json.toJSONString());

        Boolean success = json.getBoolean("success");
        String message = json.getString("message");
        String code = json.getString("code");
        //success= success==null?false:success;
        if(success==null?false:success){
            ibacklogOrFullListService.parseBacklogsJson(json);
        }

    }

    @RequestMapping(value = "/getUserByPage", method = RequestMethod.GET)
    @ApiOperation(value = "测试getUserByPage")
    public  void  getUserByPage(@ModelAttribute PageVo page){
        page.setPageNumber(1);
        page.setPageSize(10);
        IPage<User> userByPage = iUserService.getUserByPage(PageUtil.initMpPage(page));
        List<User> records = userByPage.getRecords();
        for (User user : records) {
            log.info(user.getIdcard());
        }
    }

    @RequestMapping(value = "/logsTest", method = RequestMethod.GET)
    @ApiOperation(value = "logsTest")
    public  void  logsTest(){
        String   datas="<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\" +\n" +
                "                \"\\t<sendData>\\n\" +\n" +
                "                \"\\t\\t<totalRecord>1139</totalRecord>\\n\" +\n" +
                "                \"\\t\\t<totalPage>6</totalPage>\\n\" +\n" +
                "                \"\\t\\t<pageSize>200</pageSize>\\n\" +\n" +
                "                \"\\t\\t<currentPage>1</currentPage>\\n\" +\n" +
                "                \"\\t\\t<taskId>7DB30B4FA31C9E2CB2834615FAB987FB</taskId>\\n\" +\n" +
                "                \"\\t\\t<datas>\\n\" +\n" +
                "                \"\\t\\t\\t<data tableName=\\\"MD_MIDSTAFF\\\">\\n\" +\n" +
                "                \"\\t\\t\\t\\t<createUnit>--</createUnit>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<recid>358DBF39A1CBA1ADCDB0A70FEC503D5C</recid>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<version>8003606935628677633</version>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"STDCODE\\\" type=\\\"2\\\" value=\\\"430104195907111520\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"STDNAME\\\" type=\\\"2\\\" value=\\\"黄汉莲停用try\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"A0177\\\" type=\\\"2\\\" value=\\\"430104195907111520\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"FLAG\\\" type=\\\"2\\\" value=\\\"3\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"A0148\\\" type=\\\"2\\\" value=\\\"13627423398\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"LEVEL\\\" type=\\\"3\\\" value=\\\"1\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"ISLEAF\\\" type=\\\"4\\\" value=\\\"true\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"SORTORDER\\\" type=\\\"1\\\" value=\\\"13301.0\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"INVALIDTIME\\\" type=\\\"6\\\" value=\\\"9999-12-31 00:00:00\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"VALIDTIME\\\" type=\\\"6\\\" value=\\\"1990-01-01 00:00:00\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t\\t<field name=\\\"PARENTS\\\" type=\\\"10\\\"/>\\n\" +\n" +
                "                \"\\t\\t\\t</data>\\n\" +\n" +
                "                \"\\t\\t\\t</datas>\\n\" +\n" +
                "                \"\\t</sendData>";
        //日志文件压缩测试
        int i=0;
        while(i<100000) {
            log.info(datas);

            i++;
        }
    }

    @RequestMapping(value = "/backlogTest", method = RequestMethod.GET)
    @ApiOperation(value = "backlogTest测试")
    public  void  backlogTest(){
        PageVo page=new PageVo(6,500);
        IPage<User> userByPage = iUserService.getUserByPage(PageUtil.initMpPage(page));
        List<User> userlist = userByPage.getRecords();
        JSONObject jsonObject = new BacklogUtile().javaToJSON(userlist);
        RestTemplate restTemplate=new RestTemplate();
        String url="http://61.187.10.181:9799/getBacklogByCondition";
        JSONObject json = restTemplate.postForEntity(url, jsonObject, JSONObject.class).getBody();
        log.info("待办初始化接口返回报文:"+json.toJSONString());
    }


    /**
     * 向目的URL发送post请求
     *
     *
     * @return  ResultVO
     */
    /*public static ResultVO sendPostRequest(String url, MultiValueMap<String, String> params){
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        HttpMethod method = HttpMethod.POST;
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        //执行HTTP请求，将返回的结构使用ResultVO类格式化
        ResponseEntity<ResultVO> response = client.exchange(url, method, requestEntity, ResultVO.class);

        return response.getBody();
    }*/
    public static void main(String[] args) {
        RestTemplate restTemplate=new RestTemplate();
        JSONObject jsonObject = new CallApiUtil().javaToJSON();

        //20200703 todo  restTemplate.postForEntity("10.1.13.14:8030/getBacklogByCondition");

        JSONObject json = restTemplate.postForEntity("http://10.1.13.14:8030/getBacklogByCondition", jsonObject, JSONObject.class).getBody();
        System.out.println(json.toJSONString());
    }


    }




